home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume24 / untic < prev    next >
Encoding:
Internet Message Format  |  1991-06-05  |  27.4 KB

  1. Subject:  v24i086:  Decompile terminfo terminal descriptions
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 21079a05 55eb8da5 44e611ae 33e2407b
  5.  
  6. Submitted-by: Dave Regan <regan@jacobs.cs.orst.edu>
  7. Posting-number: Volume 24, Issue 86
  8. Archive-name: untic2
  9.  
  10.  
  11. Enclosed is an update to "untic" which first appeared in volume 5 of
  12. comp.sources.unix in 1986.  It takes a compiled terminfo(3) description
  13. of a terminal and dumps it in a format comatible with infocmp so
  14. that a new description can be added to the terminfo database.
  15.  
  16. This program is for System V machines which use the "terminfo" database,
  17. and do not have access to the AT&T program called "infocmp".
  18.  
  19. This program has been updated to include all of the current terminal
  20. characteristics, as well as emiting the output in a fashion that is
  21. compatible with "infocmp".
  22.  
  23.  
  24.                 Dave Regan
  25.                 regan@jacobs.cs.orst.edu
  26. -------------------------------------------------------------------
  27. #! /bin/sh
  28. # This is a shell archive.  Remove anything before this line, then unpack
  29. # it by saving it into a file and typing "sh file".  To overwrite existing
  30. # files, type "sh file -c".  You can also feed this as standard input via
  31. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  32. # will see the following message at the end:
  33. #        "End of shell archive."
  34. # Contents:  README Makefile untic.1 untic.c untic.tst
  35. # Wrapped by regan@regan-h on Mon Dec 10 23:22:53 1990
  36. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  37. if test -f README -a "${1}" != "-c" ; then 
  38.   echo shar: Will not over-write existing file \"README\"
  39. else
  40. echo shar: Extracting \"README\" \(1216 characters\)
  41. sed "s/^X//" >README <<'END_OF_README'
  42. Xuntic -- Decompile a "terminfo" terminal description file for System V.
  43. X
  44. XI wrote the following program, "untic", because I needed to make a terminal
  45. Xdescription file which was just slightly different from one of the existing
  46. Xterminal descriptions.
  47. X
  48. XThis program looks up the description directly from the compiled description
  49. Xfile.  Thus it produces a file, which when compiled, generated exactly the
  50. Xsame information as was in the original file.
  51. X
  52. XThis "shar" file contains the following files:
  53. X    README        This file
  54. X    untic.1        A (very simple) manual page
  55. X    Makefile    A (very simple) make file
  56. X    untic.c        The program
  57. X    untic.tst    A simple test script to compare against "infocmp"
  58. X
  59. XThis was written long ago, before "infocmp" was available.  This was
  60. Xpublished in volume 5 of comp.sources.unix in May of 1986.  At the request
  61. Xof Joe Wasik from the Unix/C Reusable Code Library, I have updated this
  62. Xprogram to a more modern version of System V.  Evidentally, not all sites
  63. Xwhich have the terminfo terminal descriptions have "infocmp".
  64. X
  65. XIf "infocmp" is available at your site, then this program is of no real use;
  66. Xinfocmp does all this does, plus a whole lot more.
  67. X
  68. X            Dave Regan
  69. X            10 December 1990
  70. X            regan@jacobs.cs.orst.edu
  71. END_OF_README
  72. if test 1216 -ne `wc -c <README`; then
  73.     echo shar: \"README\" unpacked with wrong size!
  74. fi
  75. # end of overwriting check
  76. fi
  77. if test -f Makefile -a "${1}" != "-c" ; then 
  78.   echo shar: Will not over-write existing file \"Makefile\"
  79. else
  80. echo shar: Extracting \"Makefile\" \(361 characters\)
  81. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  82. XCFLAGS = -DSYSVR3 -DSTRICT_TERMINFO_COMPATIBILITY -O
  83. XDESTDIR = /usr/local/bin
  84. XDOCDIR = /usr/local/man/man1
  85. X
  86. Xuntic:    untic.c
  87. X    $(CC) $(CFLAGS) untic.c -o untic
  88. X
  89. Xlint:
  90. X    lint untic.c
  91. X
  92. Xinstall:    untic
  93. X    cp untic $(DESTDIR)/untic
  94. X    strip $(DESTDIR)/untic
  95. X#    cp untic.1 $(DOCDIR)/untic.1
  96. X
  97. Xclean:
  98. X    rm untic
  99. X
  100. Xshar:
  101. X    shar README Makefile untic.1 untic.c untic.tst >untic.shar
  102. END_OF_Makefile
  103. if test 361 -ne `wc -c <Makefile`; then
  104.     echo shar: \"Makefile\" unpacked with wrong size!
  105. fi
  106. # end of overwriting check
  107. fi
  108. if test -f untic.1 -a "${1}" != "-c" ; then 
  109.   echo shar: Will not over-write existing file \"untic.1\"
  110. else
  111. echo shar: Extracting \"untic.1\" \(1508 characters\)
  112. sed "s/^X//" >untic.1 <<'END_OF_untic.1'
  113. X.TH UNTIC 1 Public Domain
  114. X.SH NAME
  115. Xuntic \- Uncompile terminfo terminal description files
  116. X.SH SYNOPSIS
  117. X.B untic
  118. X.B terminal_name
  119. X[
  120. X.B . . .
  121. X]
  122. X.SH DESCRIPTION
  123. X.B untic
  124. Xconvert the terminfo file which corresponds to the specified terminal name
  125. Xinto a file that can be processed by
  126. X.B tic.
  127. X.PP
  128. XIf multiple terminal names are given, a terminal description is generated
  129. Xfor each of the named terminals.
  130. XThe output is written on standard output.
  131. X.PP
  132. XIt is wise to backup the original terminal description
  133. X(from /usr/lib/terminfo)
  134. Xbefore compiling the generated file.
  135. X.PP
  136. XNormally, terminal descriptions are found in "/usr/lib/terminfo".
  137. XHowever, if the environment variable "TERMINFO" exists, then
  138. Xthe value of that variable is used as the path of terminal descriptions.
  139. X.SH EXAMPLES
  140. XTo uncompile the terminal description for a "vt100", type:
  141. X.RS
  142. Xuntic vt100 >vt100
  143. X.RE
  144. XTo compile this generated file, you probably need root permissions and type:
  145. X.RS
  146. Xtic vt100
  147. X.RE
  148. X.SH NOTES
  149. XIf new capabilities are added to the terminfo database,
  150. Xthe
  151. X.B untic
  152. Xprogram will need to be modified.
  153. XWith luck, the new entries will go at the end of the appropriate tables.
  154. X.PP
  155. XMost of the capabilities are in the tables in the order that the capabilites
  156. Xare documented.
  157. XThere are a few exceptions in the string variables.
  158. X.PP
  159. XThis program is placed into the public domain.
  160. XThat means that you can do anything you want to with it.
  161. X.SH BUGS
  162. XNone known, but . . .
  163. X.SH FILES
  164. XThe terminal descriptions are stored in
  165. X.B /usr/lib/terminfo/?/*
  166. END_OF_untic.1
  167. if test 1508 -ne `wc -c <untic.1`; then
  168.     echo shar: \"untic.1\" unpacked with wrong size!
  169. fi
  170. # end of overwriting check
  171. fi
  172. if test -f untic.c -a "${1}" != "-c" ; then 
  173.   echo shar: Will not over-write existing file \"untic.c\"
  174. else
  175. echo shar: Extracting \"untic.c\" \(18844 characters\)
  176. sed "s/^X//" >untic.c <<'END_OF_untic.c'
  177. X/*
  178. X * Untic.c -- Uncompile a terminfo file
  179. X *
  180. X * Usage:
  181. X *    untic terminal_name . . .
  182. X *
  183. X * This program finds the terminal description in
  184. X *    /usr/lib/terminfo/?/terminal_name
  185. X * It then converts the information into an ASCII file suitable for
  186. X * running into "tic".  The resulting file is written to standard output.
  187. X *
  188. X * Compile by:
  189. X *    cc -DSYSVR3 -O -o untic untic.c
  190. X *
  191. X * It is probably a good idea to ensure that the file produced will compile
  192. X * to the original file before trusting "untic".
  193. X *
  194. X * Structure of terminfo file:
  195. X *    short    magic number
  196. X *    short    length of terminal names + NUL
  197. X *    short    length of booleans
  198. X *    short    length of numerics
  199. X *    short    length of strings
  200. X *    short    length of string table
  201. X *    chars    NUL terminated terminal name
  202. X *    chars    boolean flags for each of the possible booleans
  203. X *    shorts    values for each of the possible numerics
  204. X *    shorts    offsets (from start of strings) for each of the
  205. X *        possible strings
  206. X *    chars    NUL terminated strings for each of the defined strings
  207. X *
  208. X * Most of the variables are in the order that the documentation lists
  209. X * them.  This is important, as the information is stored in the file
  210. X * based upon the ordinal position of the variable.  Some of the string
  211. X * variables are not in order.  Presumably, if they add more variables,
  212. X * it will be to the end of the list, and not in the middle.
  213. X *
  214. X * This has been tested on
  215. X *    Plexus P20 (M68010), System 5 Release 2 (I think)
  216. X *
  217. X * Bugs:
  218. X *    The longest string capability is limited to 4096 bytes.  If a longer
  219. X *    string is encountered, the program will do unpredicatable things.
  220. X *    (Who uses strings that long anyway?)  The longest that the terminfo
  221. X *    file can be is 4096 bytes anyway, so this isn't too big a problem.
  222. X *
  223. X * Credits:
  224. X *    Written by Dave Regan    orstcs!regan    16 May 86
  225. X *    TERMINFO environment variable added by G A Moffett (amdahl!gam)
  226. X *        31 May 86
  227. X *    TERMINFO environment variable added by hp-pcd!hplabs!csun!aeusemrs
  228. X *    (again) 16 Jan 87.  Time to get this out.
  229. X *
  230. X *    I disclaim that this program does anything useful.  It might also
  231. X *    do accidental damage.  Backup your original terminfo files.
  232. X *
  233. X *    This program is public domain.  That means you can do anything
  234. X *    you want with it.
  235. X *
  236. X *        New Notes        16 Jan 1987
  237. X *    I want to thank the people who have written to me to let
  238. X *    me know that they have a use for this program, and have added
  239. X *    suggestions.  I am also glad that Unipress have this tool on
  240. X *    their distribution tape.
  241. X *
  242. X *    It has been brought to my attention (by Tony Hansen -
  243. X *    ihnp4!pegasus!hansen) that there is a program in the ATT toolchest
  244. X *    and to be distributed in system V, release 3 called "infocmp" that
  245. X *    does what "untic" does, as well as a lot more.  See the System V
  246. X *    Administration Guide.
  247. X *
  248. X *            Thanks to everyone who gave me information,
  249. X *            Dave Regan    16 Jan 87
  250. X *
  251. X *
  252. X *        Notes            10 December 1990
  253. X *    I have added the capabilities necessary to support a more modern
  254. X *    version of System V.  To get these new capabilities, add -DSYSVR3
  255. X *    to the command line.  In general, it should not hurt to have too many
  256. X *    capabilities in this list, as long as it is a strict superset of
  257. X *    what you have in your "tic".  (These changes were basically noted
  258. X *    by Kirk Webb (kirk@ico.ISC.COM) on 13 Feb 1987.  I have added
  259. X *    some beyond what he had called out.)
  260. X *
  261. X *    If it comes to figuring out why this doesn't work, run "strings -2"
  262. X *    on the Terminfo Compiler (tic) and look at the output.  You should
  263. X *    see the tables of capabilities go by.  Copy these capabilities
  264. X *    into the appropriate tables, and you should be fine.
  265. X *
  266. X *    Some of the terminfo compilers have more symbols than others.
  267. X *    I modified the error checking to not emit an error unless one of
  268. X *    the "extended" symbols is actually referenced.
  269. X *
  270. X *    I have added "void" as a return type to some of the functions.
  271. X *    If this gives your C compiler a fit, then do a "-Dvoid=int" on
  272. X *    the command line.
  273. X *
  274. X *    Thanks to Joe Wasik at the Unix/C Reusable Code Library
  275. X *    (jcwasik@clib.PacBell.COM) to get me to put this together
  276. X *    again with current tables.  The test program (untic.tst) was
  277. X *    also written by him.
  278. X *
  279. X *    It appears that current versions of infocmp will somehow derive
  280. X *    the "ma#1" capability on older terminfo files.  I have looked
  281. X *    at the various terminfo files in reasonable detail, and cannot
  282. X *    figure out how it can tell the difference.  So I am punting,
  283. X *    and simply enumerate all of the "special" cases.  This is a
  284. X *    gross hack, and if anyone can tell me an algorithmic way to
  285. X *    do this, I would apperciate it.  Actually, it does this even
  286. X *    on "modern" terminfo files.  See "fortune" for an example of
  287. X *    a terminfo file which could represent the "ma" capability but
  288. X *    the value is 0xFFFF (not used).  Yet, the "ma#1" capability is
  289. X *    printed by terminfo.  I am almost beginning to think that this
  290. X *    is a bug on terminfo's part, but processing it correctly is so
  291. X *    trivial, that I don't see how this could be messed up; it must
  292. X *    be by design.  Well, if you find out, let me know.
  293. X *
  294. X *            Dave Regan    10 December 1990
  295. X */
  296. X
  297. X#include <stdio.h>
  298. X#include <ctype.h>
  299. X
  300. X#ifdef __MSDOS__
  301. X#include <stdlib.h>
  302. X#include <string.h>
  303. X#define    OPEN_MODE    "rb"
  304. X#define    CVPTR        const void
  305. X#define    F(x)        x    /* Function prototypes            */
  306. X#else
  307. Xextern char *strcpy();        /* This should be in strings.h        */
  308. Xextern char *    malloc();    /* This is supposed to be in stdlib.h, but
  309. X                 * that file doesn't exist on older systems. */
  310. X#define    OPEN_MODE    "r"    /* Mode used to open terminfo files    */
  311. X#define    CVPTR        char
  312. X#define    F(x)        ()    /* No prototypes            */
  313. X#endif    /* __MSDOS__ */
  314. X
  315. X/***
  316. X ***    Local constants
  317. X ***/
  318. X#ifndef TRUE
  319. X#define    TRUE    1
  320. X#define    FALSE    0
  321. X#endif        /* TRUE */
  322. X
  323. X#define    DEBUG    FALSE        /* TRUE/FALSE to enable debugging output */
  324. X
  325. X#ifndef TERMINFO_DIR
  326. X#define    TERMINFO_DIR    "/usr/lib/terminfo"
  327. X#endif        /* TERMINFO_DIR */
  328. X
  329. X
  330. X#define    MAGIC    0x011A        /* Terminfo magic number        */
  331. X#define    MAXLINE    55        /* Longest emited line            */
  332. X#define    MAX_CAP    4096        /* Longest single capability        */
  333. X
  334. X/***
  335. X ***    Forward declarations
  336. X ***/
  337. Xextern char *    addchar F((char *cptr, int ch));
  338. Xextern char *    addoctal F((char *cptr, int ch));
  339. Xextern char *    addstr F((char *cptr, char *str));
  340. Xextern void    convert F((FILE *file, char *name));
  341. Xextern void    emit F((char *str));
  342. Xextern unsigned short get2 F((FILE *file));
  343. Xextern int    xstrcmp F((CVPTR *a, CVPTR *b));
  344. X
  345. X/***
  346. X ***    Global data
  347. X ***/
  348. Xint    Line_len;        /* Current length of line        */
  349. X
  350. X/***
  351. X ***    Definitions of attributes
  352. X ***/
  353. Xchar    *Booleans[] =    /* Names of boolean variables, in order    */
  354. X    { "bw", "am", "xsb", "xhp", "xenl", "eo", "gn", "hc", "km",
  355. X      "hs", "in", "da", "db", "mir", "msgr", "os", "eslok", "xt",
  356. X      "hz", "ul", "xon"
  357. X#ifdef SYSVR3
  358. X    , "nxon", "mc5i", "chts", "nrrmc", "npc"
  359. X    , "ndscr"
  360. X#endif    /* SYSVR3 */
  361. X     };
  362. X#define    BOOL_LENGTH    (sizeof(Booleans) / sizeof(char *))
  363. X
  364. Xchar    *Numerics[] =    /* Names of numeric variables, in order    */
  365. X    { "cols", "it", "lines", "lm", "xmc", "pb", "vt", "wsl"
  366. X#ifdef SYSVR3
  367. X    , "nlab", "lh", "lw"
  368. X    , "ma", "wnum"    
  369. X#endif    /* SYSVR3 */
  370. X    };
  371. X#define    NUM_LENGTH    (sizeof(Numerics) / sizeof(char *))
  372. X
  373. Xchar    *Strings[] =    /* Names of string variables, not in strict
  374. X                   order.  Makes things a little harder    */
  375. X    { "cbt", "bel", "cr", "csr", "tbc", "clear", "el", "ed", "hpa",
  376. X      "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup",
  377. X      "cnorm", "cuf1", "ll", "cuu1", "cvvis", "dch1", "dl1", "dsl",
  378. X      "hd", "smacs", "blink", "bold", "smcup", "smdc", "dim", "smir",
  379. X      "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", 
  380. X      "rmcup", "rmdc", "rmir", "rmso", "rmul", "flash", "ff", "fsl",
  381. X      "is1", "is2", "is3", "if", "ich1", "il1", "ip", "kbs", "ktbc",
  382. X      "kclr", "kctab", "kdch1", "kdl1", "kcud1", "krmir", "kel", "ked",
  383. X      "kf0", "kf1", "kf10", "kf2", "kf3", "kf4", "kf5", "kf6", "kf7",
  384. X      "kf8", "kf9", "khome", "kich1", "kil1", "kcub1", "kll", "knp",
  385. X      "kpp", "kcuf1", "kind", "kri", "khts", "kcuu1", "rmkx", "smkx", 
  386. X      "lf0", "lf1", "lf10", "lf2", "lf3", "lf4", "lf5", "lf6", "lf7",
  387. X      "lf8", "lf9", "rmm", "smm", "nel", "pad", "dch", "dl", "cud",
  388. X      "ich", "indn", "il", "cub", "cuf", "rin", "cuu", "pfkey", "pfloc",
  389. X      "pfx", "mc0", "mc4", "mc5", "rep", "rs1", "rs2", "rs3", "rf",
  390. X      "rc", "vpa", "sc", "ind", "ri", "sgr", "hts", "wind", "ht", "tsl",
  391. X      "uc", "hu", "iprog", "ka1", "ka3", "kb2", "kc1", "kc3", "mc5p"
  392. X#ifdef SYSVR3
  393. X    , "rmp", "acsc", "pln", "kcbt", "smxon", "rmxon", "smam", "rmam",
  394. X      "xonc", "xoffc", "enacs", "smln", "rmln", "kbeg", "kcan", "kclo",
  395. X      "kcmd", "kcpy", "kcrt", "kend", "kent", "kext", "kfnd", "khlp",
  396. X      "kmrk", "kmsg", "kmov", "knxt", "kopn", "kopt", "kprv", "kprt",
  397. X      "krdo", "kref", "krfr", "krpl", "krst", "kres", "ksav", "kspd",
  398. X      "kund", "kBEG", "kCAN", "kCMD", "kCPY", "kCRT", "kDC", "kDL",
  399. X      "kslt", "kEND", "kEOL", "kEXT", "kFND", "kHLP", "kHOM", "kIC",
  400. X      "kLFT", "kMSG", "kMOV", "kNXT", "kOPT", "kPRV", "kPRT", "kRDO",
  401. X      "kRPL", "kRIT", "kRES", "kSAV", "kSPD", "kUND", "rfi", "kf11",
  402. X      "kf12", "kf13", "kf14", "kf15", "kf16", "kf17", "kf18", "kf19",
  403. X      "kf20", "kf21", "kf22", "kf23", "kf24", "kf25", "kf26", "kf27",
  404. X      "kf28", "kf29", "kf30", "kf31", "kf32", "kf33", "kf34", "kf35",
  405. X      "kf36", "kf37", "kf38", "kf39", "kf40", "kf41", "kf42", "kf43",
  406. X      "kf44", "kf45", "kf46", "kf47", "kf48", "kf49", "kf50", "kf51",
  407. X      "kf52", "kf53", "kf54", "kf55", "kf56", "kf57", "kf58", "kf59",
  408. X      "kf60", "kf61", "kf62", "kf63", "el1", "mgc", "smgl", "smgr",
  409. X      "fln", "sclk", "dclk", "rmclk", "cwin", "wingo", "hup", "dial",
  410. X      "qdial", "tone", "pulse", "hook", "pause", "wait", "u0", "u1",
  411. X      "u2", "u3", "u4", "u5", "u6", "u7", "u8", "u9"
  412. X#endif    /* SYSVR3 */
  413. X#ifdef HPUX5
  414. X      , "meml", "memu"
  415. X#endif    /* HPUX5 */
  416. X      };
  417. X#define    STR_LENGTH    (sizeof(Strings) / sizeof(char *))
  418. X
  419. Xchar    *Exceptions[] =
  420. X    { "912b", "912cc", "920b", "adm5", "d800", "dtc", "f1720", "fortune",
  421. X      "hp", "hp110", "intext", "ofos", "pe1251", "regent100", "regent40",
  422. X      "regent40-s", "regent60", "regent60-na", "sb1", "sb2", "sbi",
  423. X      "smartvid", "t1061", "t1061f", "tec400", "trs16", "tvi2p", "tvi803",
  424. X      "tvi912", "tvi912-2p", "tvi9122p", "tvi9202p", "tvi925", "tvi925-v",
  425. X      "tvi950", "tvi950-2p", "tvi950-4p", "tvi950-ap", "tvi950-b",
  426. X      "tvi950-ns", "tvi950-rv", "tvi950-rv-2p", "tvi950-rv-4p",
  427. X      "tvi9502p", "tvi9504p", "tvi950b", "tvi950ns", "tvi950rv",
  428. X      "tvi950rv2p", "tvi950rv4p", "vt100-nav", "vt100-nav-w", "xtalk",
  429. X      "ya", NULL
  430. X    };
  431. X
  432. X/***
  433. X ***    Function definitions
  434. X ***/
  435. X
  436. Xvoid
  437. Xmain(argc, argv)
  438. X  int    argc;            /* Number of paramters            */
  439. X  char    *argv[];        /* The parameters themselves        */
  440. X    {
  441. X    char subdir[2];        /* Subdirectory name            */
  442. X    FILE *file;
  443. X    char *terminfo;
  444. X    extern FILE *fopen();
  445. X    extern char *getenv();
  446. X
  447. X    /* Change directory to the working directory            */
  448. X    terminfo = getenv("TERMINFO");
  449. X    if (terminfo == NULL) {
  450. X     terminfo = TERMINFO_DIR;
  451. X    }
  452. X#if DEBUG
  453. X    fprintf(stderr, "Looking in %s/?/... for entry.\n", terminfo);
  454. X#endif
  455. X    (void)chdir(terminfo);
  456. X
  457. X    /* Go through the arguments                        */
  458. X    subdir[1] = '\0';
  459. X    if (argc == 1)
  460. X    convert(stdin, "stdin");
  461. X    else
  462. X    {
  463. X    while (--argc)
  464. X        {
  465. X        ++argv;
  466. X        subdir[0] = argv[0][0];
  467. X        (void)chdir(subdir);
  468. X        if ((file = fopen(*argv, OPEN_MODE)) == NULL)
  469. X        {
  470. X        perror(*argv);
  471. X        }
  472. X        else
  473. X        {
  474. X        convert(file, *argv);
  475. X        (void)fclose(file);
  476. X        }
  477. X        (void)chdir("..");
  478. X        }
  479. X    }
  480. X    exit(0);
  481. X    }
  482. X
  483. X
  484. X/*
  485. X * Addchar -- Add a character
  486. X */
  487. Xchar *
  488. Xaddchar(cptr, ch)
  489. X  char    *cptr;
  490. X  int    ch;
  491. X    {
  492. X    char *addstr(), *addoctal();
  493. X
  494. X    if (ch == '\0')
  495. X    return (addstr(cptr, "\\200"));
  496. X    if (ch == 0x1B)
  497. X    return (addstr(cptr, "\\E"));
  498. X    if (ch == '\n')
  499. X    return (addstr(cptr, "\\n"));
  500. X    if (ch == '\r')
  501. X    return (addstr(cptr, "\\r"));
  502. X    if (ch == '\t')
  503. X    return (addstr(cptr, "\\t"));
  504. X    if (ch == '\b')
  505. X    return (addstr(cptr, "\\b"));
  506. X    if (ch == '\f')
  507. X    return (addstr(cptr, "\\f"));
  508. X    if (ch == ' ')
  509. X    return (addstr(cptr, "\\s"));
  510. X    if (ch == '^')
  511. X    return (addstr(cptr, "\\^"));
  512. X    if (ch == '\\')
  513. X    return (addstr(cptr, "\\\\"));
  514. X    if (ch == ',')
  515. X    return (addstr(cptr, "\\,"));
  516. X    if (ch == 0x7F)
  517. X    return (addstr(cptr, "\^?"));
  518. X    if (ch >= ('A' - '@') && ch <= ('_' - '@'))
  519. X    {
  520. X    *cptr++ = '^';
  521. X    *cptr++ = ch + '@';
  522. X    return (cptr);
  523. X    }
  524. X    if (ch > 0x7F)
  525. X        return (addoctal(cptr, ch));
  526. X    *cptr++ = ch;
  527. X    return (cptr);
  528. X    }
  529. X
  530. X
  531. X/*
  532. X * Addoctal -- Add an octal character
  533. X *
  534. X * Use sprintf just in case "0" through "7" are not contiguous.  Some
  535. X * machines are weird.
  536. X */
  537. Xchar *
  538. Xaddoctal(cptr, ch)
  539. X  char    *cptr;
  540. X  int    ch;
  541. X    {
  542. X    char *addstr();
  543. X
  544. X    ch &= 0xFF;
  545. X
  546. X    if (ch == 0x80)
  547. X    return (addstr(cptr, "\\200"));
  548. X    (void)sprintf(cptr, "\\%03o", ch);
  549. X    while (*cptr != '\0')
  550. X    cptr++;
  551. X    return (cptr);
  552. X    }
  553. X
  554. X
  555. X/*
  556. X * Addstr -- Add a string to the capability
  557. X */
  558. Xchar *
  559. Xaddstr(cptr, str)
  560. X  char    *cptr, *str;
  561. X    {
  562. X    while (*str)
  563. X    *cptr++ = *str++;
  564. X    return (cptr);
  565. X    }
  566. X
  567. X
  568. X/*
  569. X * Convert -- Do the actual conversion
  570. X */
  571. Xvoid
  572. Xconvert(file, name)
  573. X  FILE    *file;        /* The file with the compiled information    */
  574. X  char    *name;        /* Printable version of the filename        */
  575. X    {
  576. X    int    ch, val, i, j;
  577. X    int name_length, bool_length, num_length, str_length, s_length;
  578. X    char capability[MAX_CAP+1], *cptr, *addchar();
  579. X    char **scan;
  580. X    char term_name[80];
  581. X    int str_cap[STR_LENGTH];
  582. X
  583. X    /* Check the magic number out                    */
  584. X    if (get2(file) != MAGIC)
  585. X    {
  586. X    fprintf(stderr, "\"%s\" is not a terminfo file\n", name);
  587. X    return;
  588. X    }
  589. X
  590. X    /* Get the rest of the header information                */
  591. X    name_length = get2(file);    /* Get the length of the terminal names    */
  592. X    bool_length = get2(file);    /* Get the length of the booleans    */
  593. X    num_length = get2(file);    /* Get the length of the numerics    */
  594. X    str_length = get2(file);    /* Get the length of the strings    */
  595. X    s_length = get2(file);    /* Get the length of the string tables    */
  596. X
  597. X    /* Time to get real information                    */
  598. X    cptr = term_name;
  599. X    while ((ch = getc(file)) != '\0' && ch != EOF)
  600. X    {
  601. X    if (cptr != NULL)
  602. X        {
  603. X        if (ch == '|')
  604. X        {
  605. X        *cptr = '\0';
  606. X        cptr = NULL;
  607. X        }
  608. X        else
  609. X        *cptr++ = ch;
  610. X        }
  611. X    putchar(ch);
  612. X    }
  613. X    if (cptr != NULL)
  614. X    *cptr = '\0';
  615. X    printf(",\n");
  616. X
  617. X    /* Send out the non-null boolean variables                */
  618. X    Line_len = 0;
  619. X    for (i = 0; i < bool_length; i++)
  620. X    {
  621. X    if ((ch = getc(file)) != 0)
  622. X        {
  623. X        if (i < BOOL_LENGTH)
  624. X        emit(Booleans[i]);
  625. X        else
  626. X        fprintf(stderr, "Undefined boolean capability #%d\n", i);
  627. X        }
  628. X    }
  629. X    emit((char *) NULL);    /* Force output */
  630. X
  631. X    /* The rest of the file is on a 16 bit boundary, so adjust the file    */
  632. X    if ((name_length + bool_length) & 0x01)
  633. X    (void)getc(file);
  634. X
  635. X#ifdef STRICT_TERMINFO_COMPATIBILITY
  636. X    /* Bozo alert!!!  It appears that there is special code in infocmp to
  637. X     * put out ma#1 if this is a special terminfo file.  Presumably this
  638. X     * is a good default.  Definitately odd.
  639. X     */
  640. X    for (scan = Exceptions;
  641. X            *scan != NULL && strcmp(*scan, term_name) != 0; scan++)
  642. X    ;
  643. X    if (*scan != NULL)
  644. X    emit("ma#1");
  645. X    /* End bozo alert */
  646. X#endif    /* STRICT_TERMINFO_COMPATIBILITY */
  647. X
  648. X    /* Get the numeric variables                    */
  649. X    for (i = 0; i < num_length; i++)
  650. X    {
  651. X    if ((val = get2(file)) != 0xFFFF)
  652. X        {
  653. X        if (i < NUM_LENGTH)
  654. X        {
  655. X        (void)sprintf(capability, "%s#%d", Numerics[i], val);
  656. X        emit(capability);
  657. X        }
  658. X        else
  659. X        {
  660. X        fprintf(stderr, "Undefined numeric capability #%d (%d)\n",
  661. X                        i, val);
  662. X        }
  663. X        }
  664. X    }
  665. X    emit((char *) NULL);    /* Force output */
  666. X
  667. X    /* Get the string variables offsets                    */
  668. X    for (i = 0; i < str_length; i++)
  669. X    str_cap[i] = get2(file);
  670. X
  671. X    /* Get the string variables themselves                */
  672. X    for (i = 0; i < s_length; i++)
  673. X    {
  674. X    for (j = 0; j < str_length; j++)    /* Find the name    */
  675. X        if (str_cap[j] == i)
  676. X        break;
  677. X    if (j >= str_length)
  678. X        {
  679. X#if DEBUG
  680. X        fprintf(stderr, "Cannot find address %d\n", i);
  681. X#endif        /* DEBUG */
  682. X        (void)getc(file);
  683. X        continue;
  684. X        }
  685. X    if (j < STR_LENGTH)
  686. X        (void)strcpy(capability, Strings[j]);
  687. X    else
  688. X        (void) strcpy(capability, "OOPS");
  689. X    cptr = &capability[strlen(capability)];
  690. X    *cptr++ = '=';
  691. X    for (; (ch = getc(file)) != '\0' && ch != EOF; i++)
  692. X        cptr = addchar(cptr, ch);
  693. X    *cptr = '\0';
  694. X    emit(capability);
  695. X    if (j >= STR_LENGTH)
  696. X        {
  697. X        fprintf(stderr, "Undefined string capability #%d (%s)\n",
  698. X                            j, &capability[5]);
  699. X        }
  700. X    }
  701. X    emit((char *) NULL);    /* Force output */
  702. X    }
  703. X
  704. X
  705. X/*
  706. X * Emit -- Emit the string
  707. X *
  708. X * Emit the given string, and append a comma.  If the line gets too long,
  709. X * send out a newline and a tab.
  710. X *
  711. X * In order to make the output to be more directly comparable to infocmp,
  712. X * save up all of the output for a category, sort it, and then write it out.
  713. X */
  714. Xvoid
  715. Xemit(str)
  716. X  char    *str;        /* String to emit                */
  717. X    {
  718. X#ifdef SIMPLE_OUTPUT
  719. X    if (str == NULL)
  720. X    {
  721. X    Line_len = 0;
  722. X    printf("\n");
  723. X    }
  724. X    else
  725. X    {
  726. X    if (Line_len == 0)
  727. X        printf("\t");
  728. X    if ((Line_len += strlen(str) + 2) > MAXLINE)
  729. X        {
  730. X        Line_len = strlen(str) + 2;
  731. X        printf("\n\t");
  732. X        }
  733. X    printf("%s, ", str);
  734. X    }
  735. X#else    /* SIMPLE_OUTPUT */
  736. X    /* Array is over large, but will be enough */
  737. X    static char        *table[STR_LENGTH + BOOL_LENGTH + NUM_LENGTH];
  738. X    static int        next = 0;
  739. X
  740. X    int            len;
  741. X    int            scan;
  742. X
  743. X    if (str != NULL)
  744. X    {
  745. X    if ((table[next] = (char *) malloc(strlen(str) + 1)) == NULL)
  746. X        {
  747. X        fprintf(stderr, "OUT OF MEMORY\n");
  748. X        exit(1);
  749. X        }
  750. X    strcpy(table[next++], str);
  751. X    }
  752. X    else if (next > 0)
  753. X    {
  754. X    /* strcmp isn't quite the right type, but should work */
  755. X    qsort(table, next, sizeof(char *), xstrcmp);
  756. X    printf("\t");
  757. X    for (Line_len = scan = 0; scan < next; scan++)
  758. X        {
  759. X        len = strlen(table[scan]) + 2;
  760. X        if ((Line_len += len) > MAXLINE)
  761. X        {
  762. X        Line_len = len;
  763. X        printf("\n\t");
  764. X        }
  765. X        else if (Line_len != len)
  766. X        printf(" ");
  767. X        printf("%s,", table[scan]);
  768. X        free(table[scan]);
  769. X        }
  770. X    printf("\n");
  771. X    next = 0;
  772. X    }
  773. X#endif    /* SIMPLE_OUTPUT */
  774. X    }
  775. X
  776. X
  777. X/*
  778. X * Get2 -- Get a two byte number
  779. X */
  780. Xunsigned short
  781. Xget2(file)
  782. X  FILE *file;        /* The file with the compiled information    */
  783. X    {
  784. X    unsigned short        temp;
  785. X
  786. X    temp = getc(file) & 0xFF;
  787. X    return (temp + (getc(file) << 8));
  788. X    }
  789. X
  790. X
  791. X/*
  792. X * Xstrcmp -- Compare function for qsort
  793. X *
  794. X * Infocmp only compares the base string.  Strip of equals signs.
  795. X * This routine is an awful hack.  There is probably a more elegant
  796. X * way of doing this with standard routines.  One possibility would
  797. X * be to put a NUL at a possible '=', and restore it later (if one was
  798. X * destroyed).  Call strcmp in between.
  799. X */
  800. Xint
  801. Xxstrcmp(a, b)
  802. X  CVPTR            *a;
  803. X  CVPTR            *b;
  804. X    {
  805. X    char        *str1, *str2;
  806. X
  807. X    str1 = *(char **) a;
  808. X    str2 = *(char **) b;
  809. X
  810. X    while (*str1 != '\0' && *str1 != '=' &&
  811. X       *str2 != '\0' && *str2 != '=' &&
  812. X       *str1 == *str2)
  813. X    {
  814. X    str1++;
  815. X    str2++;
  816. X    }
  817. X    if ((*str1 == '\0' || *str1 == '=') &&
  818. X                (*str2 == '\0' || *str2 == '='))
  819. X    return (0);
  820. X    if (*str1 == '\0' || *str1 == '=')
  821. X    return (-1);
  822. X    if (*str2 == '\0' || *str2 == '=')
  823. X    return (1);
  824. X    return (*str1 - *str2);
  825. X    }
  826. X
  827. END_OF_untic.c
  828. if test 18844 -ne `wc -c <untic.c`; then
  829.     echo shar: \"untic.c\" unpacked with wrong size!
  830. fi
  831. # end of overwriting check
  832. fi
  833. if test -f untic.tst -a "${1}" != "-c" ; then 
  834.   echo shar: Will not over-write existing file \"untic.tst\"
  835. else
  836. echo shar: Extracting \"untic.tst\" \(2035 characters\)
  837. sed "s/^X//" >untic.tst <<'END_OF_untic.tst'
  838. X# List of file comes from stdin
  839. X# Get list with "find /usr/lib/terminfo -type f -print | sort > tlist"
  840. X#
  841. X# Written by: Joe Wasik, Unix/C Reusable Code Library
  842. X#          jcwasik@clib.PacBell.COM
  843. X#
  844. X# This compares the output of "infocmp" with "untic" for all files in the
  845. X# terminfo library.  If this does not report major problems, then "untic"
  846. X# is in working order for your machine.
  847. X#
  848. X# Of course, if you can run this script, then you have infocmp, and really
  849. X# don't need this program.
  850. X#
  851. X# Use this lib as input
  852. XTERMINFO=/usr/lib/terminfo
  853. X# Put temp files here
  854. XTMP=/tmp/untic$$
  855. X# Remove all temp files
  856. Xtrap "rm -f ${TMP} ${TMP}a infocmp.fil untic.fil; exit" 0 1 2 3
  857. X# Create check file
  858. X>${TMP}
  859. X# Read through each entry
  860. Xwhile read FILEPATH
  861. Xdo
  862. X    # get filename part
  863. X    BASENAME=`basename $FILEPATH`
  864. X    # tell user where we are
  865. X    echo FILE:$BASENAME '\c'
  866. X    # create file as base for comparison
  867. X    /usr/bin/infocmp $BASENAME > ${TMP}a
  868. X    if [ $? -ne 0 ]
  869. X    then
  870. X    echo "infocmp failed"
  871. X    continue 
  872. X    fi
  873. X    # get line 1 from infocmp file
  874. X    LINE1=`cat ${TMP}a | line`
  875. X    # get item1 from line1 from infocmp file
  876. X    TERM=`echo $LINE1 | cut -f1 -d\|`
  877. X    # tell user term name
  878. X    echo TERM:$TERM '\c'
  879. X    # see if already checked
  880. X    grep "^$TERM$" ${TMP} > /dev/null 2>&1
  881. X    if [ $? -eq 0 ]
  882. X    then
  883. X    echo 'already checked'
  884. X    continue
  885. X    fi
  886. X    # tell user this is a new one
  887. X    echo 'checking...'
  888. X    # write new term to checked list
  889. X    echo $TERM >> $TMP
  890. X    # from infocmp file, convert all entries to multi-line sorted
  891. X    # with no spaces or tabs.
  892. X    cat ${TMP}a | 
  893. X    sed -e 's/,/\
  894. X    /g' -e 's/[     ]//g' | sed -e '/^$/d' | sort > infocmp.fil
  895. X    # do same with untic output as we did with infocmp output
  896. X    ./untic $BASENAME | 
  897. X    sed -e 's/,/\
  898. X    /g' -e 's/[     ]//g' | sed -e '/^$/d' | sort > untic.fil
  899. X    if [ $? -ne 0 ]
  900. X    then
  901. X    echo "untic failed"
  902. X    continue 
  903. X    fi
  904. X    # do comparison -- allow diff to write to standard out
  905. X    diff infocmp.fil untic.fil
  906. Xdone
  907. Xecho
  908. Xecho "-- done --"
  909. Xexit 0
  910. X# @(#)untic.tst    UCLID 1.1
  911. END_OF_untic.tst
  912. if test 2035 -ne `wc -c <untic.tst`; then
  913.     echo shar: \"untic.tst\" unpacked with wrong size!
  914. fi
  915. # end of overwriting check
  916. fi
  917. echo shar: End of shell archive.
  918. exit 0
  919.